<?php
declare(strict_types=1);
namespace Service\WebSocketService;
use Service\BaseService;
use Service\Code\Normal;
use App\Model\PssModel\Manager;
use App\Model\PssLogModel\ManagerLog;
use Service\FileService\UploadFileService;
use Service\UserService\SupplierUserService;

/**
 * websocket 服务中间层中心
 * @author Administrator
 *
 */
class BaseWebSocketService extends BaseService
{
    protected $server;
    
    /**
     * 管理员id
     * @access protected
     * @var    int
     */
    protected $manager_id;
    
    /**
     * 管理员名称
     * @access protected
     * @var    string
     */
    protected $manager_name;
    
    /**
     * 管理员帐号
     * @var string
     */
    protected $manager_account;
    
    /**
     * 认证中心授权信息,全局通用
     * @var string
     */
    protected $systemInfo;
    
    /**
     * 获取本地用户信息
     * @var 系统信息
     */
    protected $sysInfo;
    
    /**
     * 客户端连接ID
     * @var int
     */
    protected $fd;
    
    /**
     * 访问HOST
     * @var string
     */
    protected $host;
    
    /**
     * web socket 双向通讯两个服务和客户端信息参数
     * @param $server
     * @param int $client_id
     * @param array $requestBody
     */
    public function onMessage($server,int $fd,array $param)
    {
        $this->fd = $fd;
        $this->server = $server;
        $res = $this->checkParameters($param);
        if( $res['code'] != Normal::SUC ) {
            return $this->push(Normal::returnWsStatus(Normal::WS_ERROR,$res['msg']));
        }
        
        $parameters = $res['data'];
        $res = $this->checkLogin($parameters['token']);
        if( $res['code'] != Normal::SUC ) {
            return $this->push(Normal::returnWsStatus(Normal::WS_ERROR,$res['msg']));
        }
        
        $requestMethods = explode(".", $parameters['requestMethod']);
        if( count($requestMethods) != 2 ) {
            return $this->push(Normal::returnWsStatus(Normal::WS_ERROR,"requestMethod必须满足a.b格式"));
        }
        
        $module = $requestMethods[0];
        $method = $requestMethods[1];
        $service = "Service\\WebSocketService\\WebSocketRouter\\{$module}SocketService";
        if( !class_exists($service) ) {
            return $this->push(Normal::returnWsStatus(Normal::WS_ERROR,"服务类【{$service}】不存在"));
        }
        if( !method_exists($service,$method) ) {
            return $this->push(Normal::returnWsStatus(Normal::WS_ERROR,"服务类【{$service}】方法【{$method}】不存在"));
        }
        
        $requestData = $param['requestData'];
        
        //如果存在远端文件，则需要统一读取文件数据
        $excel_header = [];
        $excel_data   = [];
        if( !empty($requestData['fileName']) ) 
        {
            $result_excel = UploadFileService::instance()->getRemoteUrlRowData($server,$fd,$requestData['fileName']);
            if( $result_excel['code'] != Normal::SUC ) {
                return $this->push(Normal::returnWsStatus(Normal::WS_ERROR,$result_excel['msg']));
            }
            
            $excel_header = $result_excel['data']['header'];
            $excel_data   = $result_excel['data']['data'];
        }
        
        //如果是供应商管理员追加供应商管理数据
        if( $this->sysInfo['is_supplier_account'] == 1 ) {
            $this->sysInfo['supplier_ids'] = SupplierUserService::instance()->queryUserBySystemUserId($this->manager_id);
        }
        
        //业务端执行完成
        $result = $service::instance()->{$method}($this->server,$fd,$requestData,$this->sysInfo,$excel_header,$excel_data);
        //读取客户端信息
        $clientInfo = $server->getClientInfo($fd);
        $remote_ip  = !empty($clientInfo['remote_ip']) ? $clientInfo['remote_ip'] : '127.0.0.1';
        
        //写入管理日志
        $data = [
            'manager_id'    => $this->manager_id,
            'manager_name'  => $this->manager_name,
            'content'       => json_encode($param,JSON_UNESCAPED_UNICODE),
            'ip'            => $remote_ip,
            'url'           => $parameters['requestMethod'],
            'cd'            => time(),
        ];
        ManagerLog::instance()->add($data);
        return $this->push($result);
    }
    
    /**
     * 向socket client push 消息
     * @param array $body
     */
    protected function push( array $body )
    {
        return $this->server->push($this->fd,json_encode($body,JSON_UNESCAPED_UNICODE));
    }
    
    /**
     * 检查登录
     * @param $param
     */
    protected function checkLogin($token)
    {
        $uid = redis()->get('mbpps_loginToken__'.$token);
        if( empty($uid) ) {
            return Normal::returnCode(Normal::NO_LOGIN,"登录失效");
        }
    
        $manage = Manager::instance()->info(['id' => $uid]);
        $this->sysInfo          = $manage;
        $this->manager_name     = $manage['name'];
        $this->manager_account  = $manage['account'];
        $this->manager_id       = $manage['id'];
        $this->role_id          = $manage['role_id'];
        return Normal::returnCode(Normal::SUC,"登录验证通过",[
            'sysInfo' => $manage
        ]);
    }
    
    /**
     * 检查 参数
     * @param $param
     */
    protected function checkParameters($param)
    {
        if ( empty($param['token']) ) {
            return Normal::returnCode(Normal::FAIL,"token参数缺失");
        }
    
        if ( empty($param['requestMethod']) ) {
            return Normal::returnCode(Normal::FAIL,"requestMethod参数缺失");
        }
    
        if ( !isset($param['requestData']) ) {
            return Normal::returnCode(Normal::FAIL,"requestData参数缺失");
        }
    
        return Normal::returnCode(Normal::SUC,"校验完成",$param);
    }
}